<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\QrCodeController;
use App\Models\Reservation;
use App\Models\ReservationApply;
use App\Models\ReservationSchedule;
use App\Models\ReservationSeat;
use App\Validate\ReservationValidate;
use Illuminate\Support\Facades\DB;

/**
 * 文化配送类
 */
class ReservationController extends CommonController
{
    protected $model;
    protected $scheduleModel;
    protected $validate;

    public function __construct()
    {
        parent::__construct();

        $this->model = new Reservation();
        $this->scheduleModel = new ReservationSchedule();
        $this->validate = new ReservationValidate();
    }

    /**
     * 获取预约参数
     */
    public function getReservationApplyParam()
    {
        $data = $this->model->getReservationApplyParam();
        return $this->returnApi(200, "获取成功", true, $data);
    }

    /**
     * 预约标签列表（预定义）
     */
    public function filterTagList()
    {
        $res = $this->definedReservationTag();

        if (!$res) {
            return $this->returnApi(203, "无数据");
        }

        return $this->returnApi(200, "查询成功", true, $res);
    }

    /**
     *  列表
     * @param node int 分类  0全部  1  人物    2  物品    3 教室   4 展览预约    5 到馆预约 6 座位预约  7 储物柜预约
     * @param page int 当前页数
     * @param limit int 分页大小
     * @param start_time int 开始时间
     * @param end_time int 结束时间
     * @param keywords string 搜索筛选
     * @param is_play int 是否发布  1.发布  2.未发布  默认2
     */
    public function lists()
    {
        $page = $this->request->page ? intval($this->request->page) : 1;
        $limit = $this->request->limit ? $this->request->limit : 10;
        $node = $this->request->node;
        $start_time = $this->request->start_time;
        $end_time = $this->request->end_time;
        $keywords = $this->request->keywords;
        $is_play = $this->request->is_play;

        $res = $this->model->lists(null, $node, $keywords, $start_time, $end_time, $is_play, $limit);

        if (empty($res['data'])) {
            return $this->returnApi(203, "暂无数据");
        }

        $res = $this->disPageData($res);
        $res['data'] = $this->addSerialNumber($res['data'], $page, $limit);

        return $this->returnApi(200, "查询成功", true, $res);
    }


    /** 
     * 详情
     * @param id int 预约id
     */
    public function detail()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('detail')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }

        $res = $this->model->with(['conSchedule' => function ($query) {
            $query->where('is_del', 1);
        }])
            ->where('id', $this->request->id)
            ->first();

        if (!$res) {
            return $this->returnApi(201, "参数传递错误");
        }

        $real_info_array = $this->model->getReservationApplyParam();
        $res->real_info_value = $this->getRealInfoArray($res->real_info, $real_info_array, 'value');
        $res->real_info_value = join("|", $res->real_info_value);

        $res = $res->toArray();
        $res['type_tag'] = $res['type_tag'] ? explode('|', $res['type_tag']) : [];
        $res['con_schedule'] = $res['con_schedule'] ? $res['con_schedule'] : [];

        /*构建排班数据*/
        if ($res['con_schedule']) {
            $week = [];
            for ($i = 1; $i <= 7; $i++) {
                $temp = [];
                $temp['week'] = $i;
                foreach ($res['con_schedule'] as $key => $value) {
                    $time_temp = [];
                    if ($i == $value['week']) {
                        $time_temp['start_time'] = $value['start_time'];
                        $time_temp['end_time'] = $value['end_time'];
                        $temp['time'][] = $time_temp;
                    }
                }
                $week[] = $temp;
            }
            $res['con_schedule'] = $week;
        }
        //判断是否可以更改是否需要绑定读者证，有人预约就不允许修改
        $apply_status = $this->model->resIsMake($this->request->id);
        $res['is_can_is_reader'] = $apply_status ? false : true; //false 有人报名，不允许修改

        return $this->returnApi(200, "查询成功", true, $res);
    }

    /**
     * 新增
     * @param node int 分类  1  师资预约    2  物品预约    3 教室   4 展览预约    5 到馆预约 6 座位预约   7 储物柜预约
     * @param img string 图片
     * @param name string 名称
     * @param intro text 简介
     * @param type_tag string 补充类型(多个|连接)
     * @param contacts string 联系人姓名
     * @param tel string 联系方式
     * @param start_age int 年龄限制开始年龄  年龄限制了才能填
     * @param end_age int 年龄限制结束年龄
     *
     * @param is_real int 是否需要用户真实信息 1需要 2不需要 默认2
     * @param astrict_sex int 性别限制   1.限男性  2.限女性  3.不限(默认)
     * @param real_info string 需要验证的真实信息id用|连接起来   1、姓名   2 、身份证号码  3、电话号码   4、读者证号码    5、真实人物头像   6、备注  7 单位名称 8 性别 9 年龄  10、附件
     * @param unit string 单位信息    物品所属单位（node为2才有）
     * @param education string 学历   人物学历（node为1才有）
     * @param kind int 物品种类 一次可预约量   1 单一物品  2 多物品（物品默认一个可预约多个（所以需要用户选择），其他都只能预约一个）  到馆 和 座位是多物品预约
     * @param number int 可预约量 默认1   多数量预约才有    5到馆预约 为总量   6 座位预约为座位个数
     * @param serial_prefix  座位预约 编号前缀 （只允许 26个字母） node 为 6 才有
     * @param day_make_time time 每日开始预约时间，这个时间之前不能预约  默认都可以预约
     * @param clock_time int 预约开始后，多少分钟之内可打卡  单位分钟  如果是储物柜，则是多少小时可领取
     * @param is_sign int 是否需要签到 1需要 2不需要
     * @param is_reader int 报名是否需要绑定读者证   1.是   2.否(默认）
     * 
     * @param return_time int 领取后，多少小时之内归还  单位小时  如果是储物柜，则是多少小时可领取
     *
     * @param is_approval int 预约是否需要审核 1需要 2不需要
     * @param is_cancel int 预约是否可以取消 1是 2否
     * @param cancel_end_time int 预约可取消最后期限(单位分钟) 等于0时没有时间限制
     * @param province string 省
     * @param city string 市
     * @param district string 区(县)
     * @param address string 详细地址
     * @param make_max_num string 每次预约限制预约个数 (node 2 才有)
     * @param sign_way int 扫码方式（node 1,2,3,4,5,6）  1 、2者都可以  2、用户自主扫码  3、管理员设备扫码 ；  钥匙选择方式（node 7）  2 用户自主选择  3 管理员选择
     * @param week string 排版信息  json 格式数据
     * @param display_day 展示可预约天数，默认7天
     * @param limit_num 限制用户可预约次数 (node 为 7,sign_way 为 2 时，这个里固定只能为1)
     *         数组样式  ['day'=>1,'time'=>[['start_time'=>'15:12:12' , 'end_time'=>'16:12:12'],['start_time'=>'15:12:12' , 'end_time'=>'16:12:12']]];
     * @param is_play 是否发布 1.发布 2.未发布    默认1
     */
    public function add()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('add')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        if (empty($this->request->number)) {
            return $this->returnApi(201, "请填写预约数量");
        }

        if ($this->request->node == 2 && !$this->request->unit) {
            return $this->returnApi(201, "请填写物品所属单位");
        }
        // if ($this->request->node == 2 && empty($this->request->make_max_num)) {
        //     return $this->returnApi(201, "请填写每次预约限制个数");
        // }
        if ($this->request->node == 1 && !$this->request->education) {
            return $this->returnApi(201, "请填写人物学历");
        }
        if ($this->request->node == 7 && (empty($this->request->return_time) || !is_numeric($this->request->return_time))) {
            return $this->returnApi(201, "归还时间规则不正确");
        }
        if ($this->request->node == 7 && ($this->request->sign_way != 2 && $this->request->sign_way != 3)) {
            return $this->returnApi(201, "钥匙选择方式规则不正确");
        }
        if (strlen($this->request->cancel_end_time) > 4) {
            return $this->returnApi(201, "最后取消期限过大,请重新填写");
        }

        if ($this->request->node == 6 || $this->request->node == 7) {
            if (!preg_match("/^[a-zA-Z]$/", $this->request->serial_prefix) && strlen($this->request->serial_prefix) != 1) {
                return $this->returnApi(201, "预约编号前缀，只能是英文字母");
            }
        }

        $is_exists = $this->model->nameIsExists($this->request->name, 'name');

        if ($is_exists) {
            return $this->returnApi(202, "此名称已存在");
        }

        /*生成经纬度*/
        $map = $this->getLonLatByAddress($this->request->province . $this->request->city . $this->request->district . $this->request->address);
        if (is_string($map)) {
            return $this->returnApi(202, $map);
        }

        //处理报名参数
        list($is_real, $real_info) = $this->model->disRealInfo($this->request->all());
        $type_tag = $this->request->type_tag;
        $type_tag = array_unique(explode('|', $type_tag));
        if (count($type_tag) > 5) {
            return $this->returnApi(202, "选择标签和自定义标签一共不能超过5个");
        }
        $type_tag = join('|', $type_tag);

        $real_info_arr = explode('|', $real_info);
        $week = $this->request->week;

        if (in_array(2, $real_info_arr) || in_array(8, $real_info_arr) && $this->request->astrict_sex) {
            $astrict_sex = $this->request->astrict_sex;
        } else {
            $astrict_sex = 3;
        }
        if (in_array(2, $real_info_arr) || in_array(9, $real_info_arr) && $this->request->start_age) {
            $start_age = $this->request->start_age;
        } else {
            $start_age = 0;
        }
        if (in_array(2, $real_info_arr) || in_array(9, $real_info_arr) && $this->request->end_age) {
            $end_age = $this->request->end_age;
        } else {
            $end_age = 0;
        }

        $data = [
            'node' => $this->request->node,
            'img' => $this->request->img ? $this->request->img : $this->getDefaultImg($this->request->node),
            'name' => $this->request->name,
            'intro' => $this->request->intro,
            'unit' => $this->request->unit,
            'type_tag' => $type_tag,
            'province' => $this->request->province,
            'city' => $this->request->city,
            'district' => $this->request->district,
            'address' => $this->request->address,
            'contacts' => $this->request->contacts,
            'tel' => $this->request->tel,
            'astrict_sex' => $astrict_sex,
            'is_real' => $is_real,
            'real_info' => $real_info,
            'start_age' => $start_age,
            'end_age' => $end_age,
            'education' => $this->request->education,
            // 'kind' => $this->request->node == 2 || $this->request->node == 5 || $this->request->node == 6 ? 2 : ($this->request->kind ? $this->request->kind : 1),
            'kind' => 2, //全部改成多物品预约
            'make_max_num' => $this->request->node == 2 ? $this->request->make_max_num : 1,
            'number' => $this->request->number,
            'serial_prefix' => ($this->request->node == 6 || $this->request->node == 7) ? strtoupper($this->request->serial_prefix) : '',
            'return_time' => $this->request->node == 7 ? $this->request->return_time : null,
            'day_make_time' => $this->request->day_make_time,
            'clock_time' => $this->request->clock_time,
            'is_reader' => $this->request->is_reader ? $this->request->is_reader : 2,
            'is_sign' => $this->request->is_sign,
            'is_approval' => $this->request->is_approval,
            'is_cancel' => $this->request->is_cancel,
            'cancel_end_time' => $this->request->cancel_end_time,
            'display_day' => !empty($this->request->display_day) ? $this->request->display_day : 7,
            'limit_num' => ($this->request->node == 7 && $this->request->sign_way == 2) ? 1 : ($this->request->limit_num ? $this->request->limit_num : null),
            'sign_way' => $this->request->sign_way ? $this->request->sign_way : 2,
            'is_play' => $this->request->is_play ? $this->request->is_play : 2,
            'lon' => $map['lon'],
            'lat' => $map['lat'],
        ];


        $qrCodeObj = new QrCodeController();
        $qr_code = $qrCodeObj->getQrCode('reservation');
        if ($qr_code === false) {
            return $this->returnApi(201, "二维码生成失败,请重新添加");
        }
        $qr_url = $qrCodeObj->setQr($qr_code, true, 360, 1);
        if (!$qr_url) {
            return $this->returnApi(202, "二维码生成失败");
        }

        $data['qr_url'] = $qr_url;
        $data['qr_code'] = $qr_code;

        // 启动事务
        DB::beginTransaction();
        try {
            //保存预约
            $this->model->add($data);

            /*维护预约排班表*/
            if ($this->request->node != 7) {
                $this->scheduleModel->add($week, $this->model->id);
            }

            //添加座位记录，或格子记录
            if ($this->request->node == 6 || $this->request->node == 7) {
                $reservationSeatObj = new ReservationSeat();
                $reservationSeatObj->change($this->model->id, $this->request->number, 0);
            }

            // 提交事务
            DB::commit();
            return $this->returnApi(200, "新增成功", true);
        } catch (\Exception $e) {
            // var_dump($e);exit;

            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }

    /** 
     * 修改
     * @param id int id
     * @param node int 分类  1  师资预约    2  物品预约    3 教室预约   4 展览预约    5 到馆预约 6 座位预约
     * @param img string 图片
     * @param name string 名称
     * @param intro text 简介
     * @param type_tag string 补充类型(多个|连接)
     * @param contacts string 联系人姓名
     * @param tel string 联系方式
     * @param start_age int 年龄限制开始年龄  年龄限制了才能填
     * @param end_age int 年龄限制结束年龄
     *
     * @param is_real int 是否需要用户真实信息 1需要 2不需要 默认2
     * @param astrict_sex int 性别限制   1.限男性  2.限女性  3.不限(默认)
     * @param real_info string 需要验证的真实信息id用|连接起来   1、姓名   2 、身份证号码  3、电话号码   4、读者证号码    5、真实人物头像   6、备注  7 单位名称 8 性别 9 年龄  10、附件
     * @param unit string 单位信息    物品所属单位（node为2才有）
     * @param education string 学历   人物学历（node为1才有）
     * @param kind int 物品种类 一次可预约量   1 单一物品  2 多物品（物品默认一个可预约多个（所以需要用户选择），其他都只能预约一个）  到馆 和 座位是多物品预约
     * @param number int 可预约量 默认1   多数量预约才有    5到馆预约 为总量   6 座位预约为座位个数  7 为格子数量
     * @param serial_prefix  座位预约 编号前缀 （只允许 26个字母） node 为 6、7 才有
     * @param day_make_time time 每日开始预约时间，这个时间之前不能预约  默认都可以预约
     * @param clock_time int 预约开始后，多少分钟之内可打卡  单位分钟  如果是储物柜，则是多少分钟可领取
     * @param is_sign int 是否需要签到 1需要 2不需要
     * @param is_reader int 报名是否需要绑定读者证   1.是   2.否(默认）
     *
     * @param return_time int 领取后，多少小时之内归还  单位小时  如果是储物柜，则是多少小时可领取
     * 
     * @param is_approval int 预约是否需要审核 1需要 2不需要
     * @param is_cancel int 预约是否可以取消 1是 2否
     * @param cancel_end_time int 预约可取消最后期限(单位分钟) 等于0时没有时间限制
     * @param province string 省
     * @param city string 市
     * @param district string 区(县)
     * @param address string 详细地址
     * @param make_max_num string 每次预约限制预约个数 (node 2 才有)
     * @param sign_way int 扫码方式（node 1,2,3,4,5,6）  1 、2者都可以  2、用户自主扫码  3、管理员设备扫码 ；  钥匙选择方式（node 7）  2 用户自主选择  3 管理员选择
     * @param week string 排版信息  json 格式数据
     * @param display_day 展示可预约天数，默认7天
     * @param limit_num 限制用户可预约次数 (node 为 7,sign_way 为 2 时，这个里固定只能为1)
     *         数组样式  ['day'=>1,'time'=>[['start_time'=>'15:12:12' , 'end_time'=>'16:12:12'],['start_time'=>'15:12:12' , 'end_time'=>'16:12:12']]];//固定是 7个时间段，不存在的时间段，也必须要有
     * @param is_play 是否发布 1.发布 2.未发布    默认1
     */

    public function change()
    {
        // dump(json_encode(['day'=>1,'time'=>[['start_time'=>'15:12:12' , 'end_time'=>'16:12:12'],['start_time'=>'15:12:12' , 'end_time'=>'16:12:12']]]));die;
        //增加验证场景进行验证
        if (!$this->validate->scene('change')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }

        if (empty($this->request->number)) {
            return $this->returnApi(201, "请填写预约数量");
        }

        if ($this->request->node == 2 && !$this->request->unit) {
            return $this->returnApi(201, "请填写物品所属单位");
        }
        // if ($this->request->node == 2 && empty($this->request->make_max_num)) {
        //     return $this->returnApi(201, "请填写每次预约限制个数");
        // }
        if ($this->request->node == 1 && !$this->request->education) {
            return $this->returnApi(201, "请填写人物学历");
        }
        if ($this->request->node == 7 && (empty($this->request->return_time) || !is_numeric($this->request->return_time))) {
            return $this->returnApi(201, "归还时间规则不正确");
        }
        if ($this->request->node == 7 && ($this->request->sign_way != 2 && $this->request->sign_way != 3)) {
            return $this->returnApi(201, "钥匙选择方式规则不正确");
        }
        if (strlen($this->request->cancel_end_time) > 4) {
            return $this->returnApi(201, "最后取消期限过大,请重新填写");
        }
        $is_exists = $this->model->nameIsExists($this->request->name, 'name', $this->request->id);

        if ($is_exists) {
            return $this->returnApi(202, "此名称已存在");
        }
        $reservation_info = $this->model->where('is_del', 1)->find($this->request->id);
        if (empty($reservation_info)) {
            return $this->returnApi(201, "参数传递错误");
        }

        if ($reservation_info->is_play == 1) {
            return $this->returnApi(201, "请先撤销，在进行修改！");
        }
        if ($this->request->node == 6 || $this->request->node == 7) {
            if ($reservation_info->serial_prefix != $this->request->serial_prefix) {
                if (!preg_match("/^[a-zA-Z]$/", $this->request->serial_prefix) && strlen($this->request->serial_prefix) != 1) {
                    return $this->returnApi(201, "预约编号前缀，只能是英文字母");
                }
                //判断是否有座位，有座位不允许修改
                $reservationSeat = new ReservationSeat();
                $seat_is_exists = $reservationSeat->seatList($this->request->id);
                if ($seat_is_exists) {
                    return $this->returnApi(201, "该预约下，已存在数据，请先删除在修改数据编号前缀");
                }
            }
        }

        //已有用户预约，不允许修改
        if ($reservation_info->is_reader !=  $this->request->is_reader) {
            //判断是否有人预约
            $reservationApplyModel = new ReservationApply();
            $apply_status = $reservationApplyModel->getMakeNumber($this->request->id, [1, 3, 6, 7]);
            if ($apply_status) {
                return $this->returnApi(201, "已有用户预约，不能修改是否需要绑定读者证参数");
            }
        }
        /*生成经纬度*/
        if ($this->request->province . $this->request->city . $this->request->district . $this->request->address != $reservation_info->province . $reservation_info->city . $reservation_info->district . $reservation_info->address) {
            $map = $this->getLonLatByAddress($this->request->province . $this->request->city . $this->request->district . $this->request->address);
            if (is_string($map)) {
                return $this->returnApi(202, $map);
            }
        }

        //处理报名参数
        list($is_real, $real_info) = $this->model->disRealInfo($this->request->all());
        $id = $this->request->id;
        $week = $this->request->week;
        $type_tag = $this->request->type_tag;
        $type_tag = array_unique(explode('|', $type_tag));
        if (count($type_tag) > 5) {
            return $this->returnApi(202, "选择标签和自定义标签一共不能超过5个");
        }
        $type_tag = join('|', $type_tag);

        $real_info_arr = explode('|', $real_info);
        $week = $this->request->week;

        if (in_array(2, $real_info_arr) || in_array(8, $real_info_arr) && $this->request->astrict_sex) {
            $astrict_sex = $this->request->astrict_sex;
        } else {
            $astrict_sex = 3;
        }
        if (in_array(2, $real_info_arr) || in_array(9, $real_info_arr) && $this->request->start_age) {
            $start_age = $this->request->start_age;
        } else {
            $start_age = 0;
        }
        if (in_array(2, $real_info_arr) || in_array(9, $real_info_arr) && $this->request->end_age) {
            $end_age = $this->request->end_age;
        } else {
            $end_age = 0;
        }

        $data = [
            'id' => $this->request->id,
            'node' => $this->request->node,
            'img' => $this->request->img ? $this->request->img : $this->getDefaultImg($this->request->node),
            'name' => $this->request->name,
            'intro' => $this->request->intro,
            'unit' => $this->request->unit,
            'type_tag' => $type_tag,
            'province' => $this->request->province,
            'city' => $this->request->city,
            'district' => $this->request->district,
            'address' => $this->request->address,
            'contacts' => $this->request->contacts,
            'tel' => $this->request->tel,
            'astrict_sex' => $astrict_sex,
            'is_real' => $is_real,
            'real_info' => $real_info,
            'start_age' => $start_age,
            'end_age' => $end_age,
            'education' => $this->request->education,
            //  'kind' => $this->request->node == 2 || $this->request->node == 5 || $this->request->node == 6 ? 2 : ($this->request->kind ? $this->request->kind : 1),
            'kind' => 2, //全部改成多物品预约
            'make_max_num' => $this->request->node == 2 ? $this->request->make_max_num : 1,
            'number' => ($this->request->node != 6 && $this->request->node != 7) ? $this->request->number : $reservation_info->number, //座位、格子个数不能改
            'serial_prefix' => ($this->request->node == 6 || $this->request->node == 7) ? strtoupper($this->request->serial_prefix) : '',
            'return_time' => $this->request->node == 7 ? $this->request->return_time : null,
            'day_make_time' => $this->request->day_make_time,
            'clock_time' => $this->request->clock_time,
            'is_reader' => $this->request->is_reader ? $this->request->is_reader : 2,
            'is_sign' => $this->request->is_sign,
            'sign_way' => $this->request->sign_way ? $this->request->sign_way : 2,
            'is_approval' => $this->request->is_approval,
            'is_cancel' => $this->request->is_cancel,
            'cancel_end_time' => $this->request->cancel_end_time,
            'display_day' => !empty($this->request->display_day) ? $this->request->display_day : 7,
            'is_play' => $this->request->is_play ? $this->request->is_play : 2,
            'limit_num' => ($this->request->node == 7 && $this->request->sign_way == 2) ? 1 : ($this->request->limit_num ? $this->request->limit_num : null),
        ];

        if (!empty($map)) {
            $data['lon'] = $map['lon'];
            $data['lat'] = $map['lat'];
        }

        //从新生产二维码
        if (empty($reservation_info['qr_url'])) {
            $qrCodeObj = new QrCodeController();
            if (empty($reservation_info['qr_code'])) {
                $qr_code = $qrCodeObj->getQrCode('reservation');
                if ($qr_code === false) {
                    return $this->returnApi(201, "二维码生成失败,请重新添加");
                }
            } else {
                $qr_code = $reservation_info['qr_code'];
            }
            $qr_url = $qrCodeObj->setQr($qr_code, true, 360, 1);
            if (!$qr_url) {
                return $this->returnApi(202, "二维码生成失败");
            }

            $data['qr_url'] = $qr_url;
            $data['qr_code'] = $qr_code;
        }

        // 启动事务
        DB::beginTransaction();
        try {
            //保存预约
            $this->model->change($data);

            /**取消已预约 */
            if ($this->request->node != 7) {
                list($weeks, $schedule_id_arr) = $this->scheduleModel->checkScheduleIsChange($week, $id);
                $applyModel = new ReservationApply();
                $schedule_table = $this->scheduleModel->getTable();
            }

            if (!empty($weeks)) {
                $reservation_apply = $applyModel
                    ->from($applyModel->getTable() . ' as a')
                    ->select('a.id', 'a.user_id', 'a.account_id', 'a.create_time', 'a.schedule_id', 'a.make_time')
                    ->join("$schedule_table as b", 'a.schedule_id', '=', 'b.id')
                    ->where('a.reservation_id', $id)
                    ->whereIn('week', $weeks)
                    ->whereIn('a.schedule_id', $schedule_id_arr) //只动修改过的排版
                    ->whereIn('status', [1, 3])
                    ->get()
                    ->toArray();

                if (!empty($reservation_apply)) {
                    $reservation_apply_ids = array_column($reservation_apply, 'id');
                    $applyModel->whereIn('id', $reservation_apply_ids)->update(['status' => 2, 'change_time' => date('Y-m-d H:i:s')]);
                }
            }

            /* 维护预约排班表*/
            if ($this->request->node != 7) {
                $this->scheduleModel->change($week, $id);
            }


            /*消息推送*/
            if (!empty($reservation_apply)) {
                $reservation_name = $reservation_info->name;
                foreach ($reservation_apply as $key => $val) {
                    $this->systemAdd("读者预约：申请失效", $val['user_id'], $val['account_id'], 34, intval($val['id']), '您申请的预约：【' . $reservation_name . '】排班已被管理员更改,您的预约已失效,请重新预约');
                }
            }
            // 提交事务
            DB::commit();
            return $this->returnApi(200, "编辑成功", true);
        } catch (\Exception $e) {
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, "编辑失败");
        }
    }

    /**
     * 删除
     * @param id int
     */
    public function del()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('del')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $reservation_info = $this->model->where('id', $this->request->id)->first();
        if (empty($reservation_info)) {
            return $this->returnApi(201, "参数传递错误");
        }
        if ($reservation_info->is_play == 1) {
            return $this->returnApi(201, "此预约已发布，撤销失败");
        }

        DB::beginTransaction();
        try {

            $res = $this->model->del($this->request->id);

            //撤销已删除的预约
            $applyModel = new ReservationApply();
            $applyInfo = $applyModel->getApplyInfo($this->request->id, null, date('Y-m-d'), '>=', [1, 3], null, null, $reservation_info['node']);
            if ($applyInfo) {
                $apply_ids = array_column($applyInfo, 'id');
                $applyModel->whereIn('id', $apply_ids)->update(['status' => 2, 'change_time' => date('Y-m-d H:i:s')]);
                foreach ($applyInfo as $key => $val) {
                    $this->systemAdd("读者预约：申请失效", $val['user_id'], $val['account_id'], 34, intval($val['id']), '您申请的预约：【' . $reservation_info->name . '】当前预约已被管理员删除,您的预约已失效,请重新预约');
                }
            }

            DB::commit();
            return $this->returnApi(200, "删除成功", true);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }

    /**
     * 发布与取消发布
     * @param ids 书籍id，多个用逗号拼接   all 是全部
     * @param is_play 是否发布  1.发布  2.未发布  默认2
     */
    public function playAndCancel()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('play_and_cancel')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        if ($this->request->is_all != 'all' && empty($this->request->ids)) {
            return $this->returnApi(201, "数据ID不能为空");
        }
        list($code, $msg) = $this->model->resumeAndCancel($this->request->ids, 'is_play', $this->request->is_play);

        $is_play = $this->request->is_play == 1 ? '发布' : '取消发布';
        if ($code === 200) {
            return $this->returnApi(200, $is_play . $msg, true);
        }
        return $this->returnApi($code, $is_play . $msg);
    }

    /**
     * 出示用户领取、归还钥匙二维码(动态二维码) （node 7 适用）  有效期3分钟
     * @param id int 预约id  
     */
    public function getReservationQr()
    {
        $res = $this->model->where('id', $this->request->id)->where('is_del', 1)->first();
        if (!$res) {
            return $this->returnApi(201, "参数传递错误");
        }
        if ($res['node'] != 7 || $res['sign_way'] != 2) {
            return $this->returnApi(201, "当前模式下不允许出示二维码");
        }

        $data['node'] = 'reservation';
        $data['qr_code'] = $res['qr_code'];
        //可以出示二维码
        $qr_url = $this->dataEncryptCreateQr($data, 5); //有效期 5分钟，前端页面置于后台时有问题
        if ($qr_url) {
            return $this->returnApi(200, "二维码生成成功", true, ['qr_url' => $qr_url, 'validity_time' => 3 * 60]); //validity_time 有效期 单位秒
        }
        return $this->returnApi(202, '二维码生成失败，请重试！');
    }

    /**
     * 获取默认占位图
     * @param node int 预约类型
     */
    public function getDefaultImg($node)
    {
        return 'default/default_make.png';
        // switch ($node) {
        //     case 1:
        //         return 'default/default_talk_make.png';
        //         break;

        //     case 2:
        //         return 'default/default_goods_make.png';
        //         break;

        //     case 3:
        //         return 'default/default_class_make.png';
        //         break;
        //     case 4:
        //         return 'default/default_room_make.png';
        //         break;
        //     default:
        //         return 'default/default_make.png';
        //         break;
        // }
    }
}
